﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class testFontScript : MonoBehaviour
{

    // Use this for initialization
    Texture2D outbuf;
    public UnityEngine.UI.RawImage uiraw;
    public UnityEngine.UI.Text uitext;
    void Start()
    {
        string outtxt = "প্রো > 2";
        //需要一个ttf文件
        var t = Resources.Load("kalpurush_data") as TextAsset;
        Debug.Log("loadasset=" + t.bytes.Length);


        //初始化freetype结构
        SharpFont.Library lib = new SharpFont.Library();
        SharpFont.Face face = new SharpFont.Face(lib, t.bytes, 0);

        //初始化harfbuzz结构
        var hbfont = harfbuzz.wrap.hb_font_create(t.bytes);
        //用harfbuzz得到glyph列表
        var list = HB_ParseString(hbfont, outtxt);


        //准备取像素
        face.SetPixelSizes(64, 0);
        outbuf = new Texture2D(512, 256, TextureFormat.ARGB32, false);

        //取
        FT_DrawFont(face, list, outbuf);

        uiraw.texture = outbuf;
        uitext.text = outtxt;
        // face.LoadGlyph(words[i].codepoint, SharpFont.LoadFlags.Default, SharpFont.LoadTarget.Normal);
    }
    static void FT_DrawFont(SharpFont.Face face, harfbuzz.hb_glyph_info_t[] list, Texture2D outtex2d)
    {
        int x = 0;
        for (var i = 0; i < list.Length; i++)
        {
            face.LoadGlyph(list[i].codepoint, SharpFont.LoadFlags.Default, SharpFont.LoadTarget.Normal);
            var addy = face.Glyph.Metrics.VerticalBearingY.ToInt32();
            var addx = face.Glyph.Advance.X.ToInt32();
            if (face.Glyph.Metrics.Width != 0)
            {
                //draw
                face.Glyph.RenderGlyph(SharpFont.RenderMode.Normal);
                var pitch = face.Glyph.Bitmap.Pitch;
                var mode = face.Glyph.Bitmap.PixelMode;
                var w = face.Glyph.Bitmap.Width;
                var h = face.Glyph.Bitmap.Rows;
                var sp = face.Glyph.Bitmap.BufferData;

                if (mode != SharpFont.PixelMode.Gray)
                    throw new System.Exception("only support gray");
                for (var sx = 0; sx < w; sx++)
                {
                    for (var sy = 0; sy < h; sy++)
                    {
                        var gray = sp[(h-sy-1) * pitch + sx];
                        var color = new Color32(255, 255, 255, gray);

                        outtex2d.SetPixel(sx + x, sy+addy , color);
                    }
                }
            }
            x += addx;
        }
        outtex2d.Apply();
    }

    static harfbuzz.hb_glyph_info_t[] HB_ParseString(harfbuzz.hb_font_t hbfont, string txt)
    {
        //初始化hbbug
        var buf = harfbuzz.wrap.hb_buffer_create();// new HarfBuzzSharp.Buffer();
        harfbuzz.wrap.hb_buffer_set_direction(buf, harfbuzz.hb_direction_t.HB_DIRECTION_LTR);//  buf.Direction = HarfBuzzSharp.Direction.LeftToRight;

        harfbuzz.wrap.hb_buffer_set_content_type(buf, harfbuzz.hb_buffer_content_type_t.HB_BUFFER_CONTENT_TYPE_UNICODE);   // buf.ContentType = HarfBuzzSharp.ContentType.Unicode;
        harfbuzz.wrap.hb_buffer_add_utf16(buf, txt); //buf.AddUtf16(outstr);
        harfbuzz.wrap.hb_buffer_guess_segment_properties(buf);    //buf.GuessSegmentProperties();//检查每一个字符串片段应该用啥方法处理

        harfbuzz.wrap.hb_shape(hbfont, buf); //hbfont.Shape(buf);//sharp之后，buf就从对应文本，变成对应字形

        //得到buf中的glyph信息列表，按这个让freetype画即可
        var hbinfo = harfbuzz.wrap.hb_buffer_get_glyph_infos(buf);// buf.GetGlyphInfoSpan();
        return hbinfo;
    }

    // Update is called once per frame
    void Update()
    {

    }
    void OnGUI()
    {
        GUILayout.Label("1.利用harfbuzz 先处理从string=>得到正确的glyph list");
        GUILayout.Label("2.再利用freetype 处理glyph");
        GUILayout.Label("3.string->glyph,glyph->bitmap应该是个双层的结构");
        GUILayout.Label("4.unityfont封装只有一层char->bitmap，所以有bug");
        GUILayout.Label("5.这个原理演示只有x64的dll 可用，但是harfbuzz和freetype都是开源的");
    }
}
